home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mgr / sparcmgr / demo3.zoo / demo / misc / maze.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-01-24  |  12.5 KB  |  515 lines

  1. /*                        Copyright (c) 1987 Bellcore
  2.  *                            All Rights Reserved
  3.  *       Permission is granted to copy or use this program, EXCEPT that it
  4.  *       may not be sold for profit, the copyright notice must be reproduced
  5.  *       on copies, and credit should be given to Bellcore where it is due.
  6.  *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
  7.  */
  8. /* mgr version */
  9. /* ************************************************************ *\
  10.  
  11.     maze.c        
  12.  
  13.     Author: JGosling
  14.     Information Technology Center
  15.     Carnegie-Mellon University
  16.  
  17.     (c) Copyright IBM Corporation, 1985
  18.     Written: 28.July.1984
  19.  
  20.  
  21. \* ************************************************************ */
  22.  
  23. static char rcsid[] = "$Header: maze.c,v 4.2 88/06/22 14:37:47 bianchi Exp $";
  24. static char IBMid[] = "(c) Copyright IBM Corporation, 1985";
  25.  
  26. /* ************************************************************ */
  27. /*                                */
  28. /*    $Log:    maze.c,v $
  29.  * Revision 4.2  88/06/22  14:37:47  bianchi
  30.  * remove version.h
  31.  * 
  32.  * Revision 4.1  88/06/21  13:42:38  bianchi
  33.  * convert copyright notice to public distribution form
  34.  * 
  35.  * Revision 2.1  88/01/19  18:00:58  bianchi
  36.  * add ckmgrterm()
  37.  * 
  38.  * Revision 1.2  87/12/18  09:28:28  bianchi
  39.  * add copyright
  40.  * 
  41.  * Revision 1.1  87/07/27  16:29:27  bianchi
  42.  * initial version
  43.  * 
  44.  * Revision 1.2  85/01/29  02:42:30  peterson
  45.  * . Add standard header and copyright
  46.  *                             */
  47. /*                                */
  48. /* ************************************************************ */
  49.  
  50. /* A simple maze wars game to test out user level graphics */
  51.  
  52. #include <stdio.h>
  53. #include "term.h"
  54. #include <errno.h>
  55. #include <sys/types.h>
  56. #include <sys/socket.h>
  57. #include <netinet/in.h>
  58. #include <netdb.h>
  59. #include <arpa/inet.h>
  60.  
  61. int errno;
  62.  
  63. int Redraw = 1;
  64. int debug = 0;
  65. int _func = -1;
  66.  
  67. #define dprintf        if(debug)fprintf
  68. #define SERVER    "mazewar"
  69.  
  70. #define M_func(n)    (_func!=n ? (m_func(n),_func=n) : 0)
  71.  
  72. #define MazeWidth 15
  73. #define MazeHeight (sizeof MazeWalls/MazeWidth)
  74. char MazeWalls[] = {
  75. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  76. 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
  77. 1,1,0,1,0,1,0,1,1,1,0,1,1,0,1,
  78. 1,0,0,1,1,1,0,0,1,0,0,0,0,1,1,
  79. 1,0,1,0,0,0,1,1,1,0,1,1,0,0,1,
  80. 1,0,1,0,1,1,0,0,0,0,1,0,1,0,1,
  81. 1,0,0,0,0,1,1,0,1,1,1,0,0,0,1,
  82. 1,1,0,1,0,1,1,0,1,1,0,0,1,0,1,
  83. 1,1,0,1,0,1,0,0,0,0,0,1,0,0,1,
  84. 1,1,0,1,1,1,1,1,0,1,1,1,0,1,1,
  85. 1,0,0,0,1,0,0,0,0,0,1,1,0,1,1,
  86. 1,0,1,1,1,1,0,1,1,0,0,0,0,1,1,
  87. 1,0,0,0,1,0,0,0,1,1,1,1,0,1,1,
  88. 1,1,1,0,0,0,1,1,1,1,1,0,0,0,1,
  89. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  90. };
  91. /*
  92. char MazeWalls[] = {
  93. 1,1,1,1,1,1,1,1,1,1,
  94. 1,0,0,0,0,0,0,0,0,1,
  95. 1,0,1,1,1,0,1,1,0,1,
  96. 1,0,0,1,0,0,0,0,1,1,
  97. 1,1,1,1,0,1,1,0,0,1,
  98. 1,0,0,0,0,1,0,1,0,1,
  99. 1,1,0,1,1,1,0,0,0,1,
  100. 1,1,0,1,1,0,0,1,0,1,
  101. 1,0,0,0,0,0,1,1,0,1,
  102. 1,1,1,1,1,1,1,1,1,1,
  103. };
  104. */
  105.  
  106. struct DirectionOffsets {
  107.     char left, right, forward, backward;
  108. } DirectionOffsets[4] = {
  109.     { -1, 1, -MazeWidth, MazeWidth }, /* facing up */
  110.     { -MazeWidth, MazeWidth, 1, -1 }, /* facing right */
  111.     { 1, -1, MazeWidth, -MazeWidth }, /* facing down */
  112.     { MazeWidth, -MazeWidth, -1, 1 }  /* facing left */
  113. };
  114.  
  115. struct state {
  116.     int id;
  117.     short position, direction;
  118. };
  119.  
  120. struct state me, him;
  121. #define HashSize 47
  122. struct state others[HashSize];
  123.  
  124. struct state *SlotsUsed[HashSize];
  125. int NOthers;
  126.  
  127. int direction = 1;
  128. int position = MazeWidth+1;
  129. int BogyDistance = 999;
  130. struct state *BogyId;
  131. int BogyRDir;
  132.  
  133. int swidth, sheight;
  134. int fwidth, fheight;
  135.  
  136. int displaystate[MazeWidth+1];
  137. int MaxDepth;
  138.  
  139. cx, cy;
  140.  
  141. #define ForwardFrom(p) ((p)+DirectionOffsets[direction].forward)
  142. #define BackwardFrom(p) ((p)+DirectionOffsets[direction].backward)
  143. #define LeftFrom(p) ((p)+DirectionOffsets[direction].left)
  144. #define RightFrom(p) ((p)+DirectionOffsets[direction].right)
  145.  
  146. #define At(p) MazeWalls[p]
  147. #define AtForward(p) MazeWalls[ForwardFrom(p)]
  148. #define AtBackward(p) MazeWalls[BackwardFrom(p)]
  149. #define AtLeft(p) MazeWalls[LeftFrom(p)]
  150. #define AtRight(p) MazeWalls[RightFrom(p)]
  151.  
  152. DrawFrom (p, w, h)
  153. register    p; {
  154.     int     depth = 0;
  155.     int     nmax = 0;
  156.     if (BogyId) {
  157.     DrawEye (BogyDistance, BogyRDir);
  158.     BogyDistance = 9999;
  159.     BogyId = 0;
  160.     }
  161.     M_func(B_INVERT);
  162.     while (!At (p) || depth <= MaxDepth) {
  163.     register    iw = w * 4 / 5;
  164.     register    ih = h * 4 / 5;
  165.     register    ThisMask = 0;
  166.     register    DoMask;
  167.     if (depth && BogyId == 0) {
  168.         register struct state **f;
  169.         for (f = SlotsUsed; *f; f++)
  170.         if ((*f) -> position == p) {
  171.             DrawEye (depth, BogyRDir = (*f) -> direction - direction);
  172.             BogyDistance = depth;
  173.             BogyId = *f;
  174.         }
  175.     }
  176.     if (!At (p)) {
  177.         nmax = depth;
  178.         if (AtLeft (p))
  179.         ThisMask |= 1 << 0;
  180.         if (AtRight (p))
  181.         ThisMask |= 1 << 1;
  182.         if (AtForward (p))
  183.         ThisMask |= 1 << 2;
  184.         if (!AtLeft (p) && AtForward (LeftFrom (p)))
  185.         ThisMask |= 1 << 3;
  186.         if (!AtRight (p) && AtForward (RightFrom (p)))
  187.         ThisMask |= 1 << 4;
  188.         if (((AtRight (p) + AtForward (p) + AtRight (ForwardFrom (p))) & 1)
  189.             || (AtRight (p) && AtForward (p)))
  190.         ThisMask |= 1 << 5;
  191.         if (((AtLeft (p) + AtForward (p) + AtLeft (ForwardFrom (p))) & 1)
  192.             || (AtLeft (p) && AtForward (p)))
  193.         ThisMask |= 1 << 6;
  194.         p = ForwardFrom (p);
  195.     }
  196.     DoMask = depth > MaxDepth ? ThisMask : displaystate[depth] ^ ThisMask;
  197.     displaystate[depth] = ThisMask;
  198.  
  199. /****************************************************************/
  200.  
  201.     if (DoMask & (1 << 0)) {
  202.         m_go (cx - w + 1, cy - h + 1);
  203.         m_draw (cx - iw, cy - ih);
  204.         m_go (cx - w + 1, cy + h - 1);
  205.         m_draw (cx - iw, cy + ih);
  206.     }
  207.     if (DoMask & (1 << 1)) {
  208.         m_go (cx + w - 1, cy - h + 1);
  209.         m_draw (cx + iw, cy - ih);
  210.         m_go (cx + w - 1, cy + h - 1);
  211.         m_draw (cx + iw, cy + ih);
  212.     }
  213.     if (DoMask & (1 << 2)) {
  214.         m_go (cx - iw, cy - ih);
  215.         m_draw (cx + iw, cy - ih);
  216.         m_go (cx - iw, cy + ih);
  217.         m_draw (cx + iw, cy + ih);
  218.     }
  219.     if (DoMask & (1 << 3)) {
  220.         m_go (cx - w + 1, cy - ih);
  221.         m_draw (cx - iw, cy - ih);
  222.         m_go (cx - w + 1, cy + ih);
  223.         m_draw (cx - iw, cy + ih);
  224.     }
  225.     if (DoMask & (1 << 4)) {
  226.         m_go (cx + w - 1, cy - ih);
  227.         m_draw (cx + iw, cy - ih);
  228.         m_go (cx + w - 1, cy + ih);
  229.         m_draw (cx + iw, cy + ih);
  230.     }
  231.     if (DoMask & (1 << 5)) {
  232.         m_go (cx + iw, cy - ih);
  233.         m_draw (cx + iw, cy + ih);
  234.     }
  235.     if (DoMask & (1 << 6)) {
  236.         m_go (cx - iw, cy - ih);
  237.         m_draw (cx - iw, cy + ih);
  238.     }
  239.     w = iw;
  240.     h = ih;
  241.     depth++;
  242.     }
  243.     MaxDepth = nmax;
  244. }
  245.  
  246. FlagRedraw () {
  247.     Redraw++;
  248. }
  249.  
  250. CanSee (him) {
  251.     register    p;
  252.     register    depth = 1;
  253.     for (p = position; ((p = ForwardFrom (p)), p>0 && p<MazeWidth*MazeWidth && !At (p)); depth++)
  254.     if (p == him)
  255.         return depth;
  256.     return 0;
  257. }
  258.  
  259. DrawEye (depth, rdir) {
  260.     register    r = cy < cx ? cy : cx;
  261.     register    sr;
  262.     while (--depth >= 0)
  263.     r = r * 4 / 5;
  264.     sr = r / 3;
  265.     m_go (cx - sr, cy - r);
  266.     m_draw (cx + sr, cy - r);
  267.     m_draw (cx + r, cy - sr);
  268.     m_draw (cx + r, cy + sr);
  269.     m_draw (cx + sr, cy + r);
  270.     m_draw (cx - sr, cy + r);
  271.     m_draw (cx - r, cy + sr);
  272.     m_draw (cx - r, cy - sr);
  273.     m_draw (cx - sr, cy - r);
  274.     while (rdir < 0)
  275.     rdir += 4;
  276.     switch (rdir) {
  277.     case 2: 
  278.         m_go (cx - r, cy);
  279.         m_draw (cx, cy - sr);
  280.         m_draw (cx + r, cy);
  281.         m_draw (cx, cy + sr);
  282.         m_draw (cx - r, cy);
  283.         break;
  284.     case 3: 
  285.         m_go (cx - r, cy - sr);
  286.         m_draw (cx, cy);
  287.         m_draw (cx - r, cy + sr);
  288.         break;
  289.     case 1: 
  290.         m_go (cx + r, cy - sr);
  291.         m_draw (cx, cy);
  292.         m_draw (cx + r, cy + sr);
  293.         break;
  294.     }
  295. }
  296.  
  297. DrawMaze (xo, yo, width, height) {
  298.     register    x,
  299.                 y;
  300.     M_func(B_OR);
  301.     for (x = 0; x < MazeWidth; x++)
  302.     for (y = 0; y < MazeHeight; y++)
  303.         if (At (y * MazeWidth + x))
  304.                 m_bitwrite(xo + x * width / MazeWidth,
  305.             yo + y * height / MazeHeight,
  306.             (x + 1) * width / MazeWidth - x * width / MazeWidth ,
  307.             (y + 1) * height / MazeHeight - y * height / MazeHeight );
  308. }
  309.  
  310. DrawAllArrows () {
  311.     register struct state **f;
  312.     DrawArrow (position,direction);
  313.     for (f = SlotsUsed; *f; f++)
  314.     DrawArrow ((*f)->position,(*f)->direction);
  315. }
  316.  
  317. DrawArrow (position, direction) {
  318.     static char *arrow[4] = {
  319.     "^", ">", "v", "<"
  320.     };
  321.     register    x = position % MazeWidth;
  322.     register    y = position / MazeWidth;
  323.     M_func(B_XOR);
  324.     m_moveprint ((((x << 1) + 1) * swidth / MazeWidth) >> 1,
  325.         ((((y << 1) + 1) * cy / MazeHeight) >> 1) + cy * 2 + (fheight>>1),
  326.         arrow[direction]);
  327.     m_movecursor(0,0);
  328. }
  329.  
  330. UpdateOther () {
  331.     register struct state  *s = &others[him.id % HashSize];
  332.     register dist;
  333.     while (s -> id && s -> id != him.id) {
  334.     s--;
  335.     if (s < others)
  336.         s = others + HashSize - 1;
  337.     }
  338.     M_func(B_XOR);
  339.     if (s -> id == 0)
  340.     SlotsUsed[NOthers++] = s;
  341.     else {
  342.     DrawArrow (s -> position, s -> direction);
  343.     if (s == BogyId) {
  344.         DrawEye (BogyDistance, BogyRDir);
  345.         BogyDistance = 9999;
  346.         BogyId = 0;
  347.     }
  348.     }
  349.     if ((dist = CanSee (him.position)) && dist<BogyDistance) {
  350.     BogyDistance = dist;
  351.     BogyId = s;
  352.     DrawEye (BogyDistance, BogyRDir = him.direction - direction);
  353.     }
  354.     *s = him;
  355.     DrawArrow (s -> position, s -> direction);
  356. }
  357.  
  358. struct sockaddr_in  sin, sout;
  359.  
  360. int     RecvSocket,
  361.         SendSocket,
  362.         rmask;
  363.  
  364. main( argc, argv )
  365. int    argc;
  366. char    *argv[];
  367. {
  368.     char *getenv();
  369.     int net;
  370.     struct hostent *hp;
  371.     struct servent *sp;
  372.     struct netent  *np;
  373.     char host[32];
  374.     int id;
  375.  
  376.     ckmgrterm( *argv );
  377.  
  378.     if (getenv("DEBUG")) {
  379.        debug++;
  380.        }
  381.  
  382.     m_setup(0);
  383.     m_push(P_FLAGS|P_EVENT);
  384.     m_setmode(M_ABS);
  385.     m_setmode(M_OVERSTRIKE);
  386.     M_func(B_SRC);
  387.     m_setevent(REDRAW,"R");
  388.     m_setevent(RESHAPE,"R");
  389.     m_ttyset();
  390.     m_setraw();
  391.     m_setnoecho();
  392.  
  393.     if ((RecvSocket = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
  394.        perror("recv socket");
  395.     if ((SendSocket = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
  396.        perror("send socket");
  397.  
  398.     rmask = (1 << fileno (m_termin)) | (1 << RecvSocket);
  399.     gethostname(host,sizeof(host)-1);
  400.     if ((hp=gethostbyname(host)) == NULL)
  401.        perror("gethostbyname");
  402.     if ((sp=getservbyname(SERVER,"udp")) ==0)
  403.        perror("Unknown service");
  404.     net = inet_netof(*((struct in_addr *)hp->h_addr));
  405.     id = inet_lnaof(*((struct in_addr *)hp->h_addr));
  406.  
  407.     sin.sin_family = hp->h_addrtype;
  408.     if (sp>0) {
  409.         sin.sin_port = sp->s_port;
  410.         sin.sin_addr = inet_makeaddr(net,INADDR_ANY);
  411.         setsockopt (RecvSocket, SOL_SOCKET, SO_REUSEADDR, 0, 0);
  412.         sout = sin;
  413.         }
  414.  
  415.     dprintf(stderr,"host: %s port: %ld, network %d service: %s\n",
  416.            hp->h_name, sp->s_port, net, sp->s_name);
  417.     if (bind (RecvSocket, &sin, sizeof sin) < 0)
  418.     perror ("bind");
  419.  
  420.     me.id = (getpid () << 16) + id;
  421.  
  422.     FlagRedraw ();
  423.     while (1) {
  424.         me.position = position;
  425.         me.direction = direction;
  426.         if (sp>0 && sendto (SendSocket, (char *) &me, sizeof me, 0, &sout, sizeof sout)
  427.                         != sizeof me)
  428.         perror ("sendto");
  429.             else
  430.                 dprintf(stderr,"Sent %d %d %d\n",
  431.                         me.id,me.direction,me.position);
  432.     if (Redraw) {
  433.             get_size(0,0,&swidth,&sheight);
  434.             get_font(&fwidth,&fheight);
  435.         M_func(B_SET);
  436.         cx = swidth / 2;
  437.         cy = sheight / 3;
  438.         m_clear();
  439.         DrawMaze (0, 2 * cy, swidth, cy);
  440.         Redraw = 0;
  441.         MaxDepth = -1;
  442.     }
  443.     DrawFrom (position, cx, cy);
  444.     M_func(B_OR);
  445.     DrawAllArrows ();
  446.     {
  447.         register    op = position;
  448.         register    c;
  449.         while (1) {
  450.         int     raction = rmask;
  451.         m_flush();
  452.                 dprintf(stderr,"Select %x...",raction); fflush(stderr);
  453.         select (32, &raction, 0, 0, 0);
  454.                 dprintf(stderr," got %x\n",raction);
  455.         if ((raction & (1 << RecvSocket))
  456.             && read (RecvSocket, (char *)&him, sizeof him) == sizeof him) {
  457.                     dprintf(stderr,"Got %d (%d) %d %d\n",
  458.                             him.id,me.id,him.direction,him.position);
  459.             if (him.id != me.id && him.direction < 4)
  460.             UpdateOther ();
  461.         }
  462.         else
  463.             perror ("read");
  464.         if (Redraw || (raction & (1 << fileno (m_termin))))
  465.             break;
  466.         };
  467.         if (!Redraw) {
  468.         c = getc (m_termin);
  469.             M_func(B_OR);
  470.         DrawAllArrows ();
  471.         }
  472.         else
  473.         if (errno != EINTR)
  474.             break;
  475.         else {
  476.             errno = 0;
  477.             continue;
  478.         }
  479.         switch (c & 0177) {
  480.         case ' ': 
  481.         case 'f': 
  482.         case '8': 
  483.             position = ForwardFrom (position);
  484.             break;
  485.         case 'l': 
  486.         case '4': 
  487.             if (--direction < 0)
  488.             direction = 3;
  489.             break;
  490.         case 'r': 
  491.         case '6': 
  492.             if (++direction > 3)
  493.             direction = 0;
  494.             break;
  495.         case 'b': 
  496.         case '2': 
  497.             position = BackwardFrom (position);
  498.             break;
  499.                 case 'R':
  500.                     FlagRedraw();
  501.                     break;
  502.         case 'q': 
  503.         case 3:     /* ^C */
  504.             m_ttyreset();
  505.                     m_clear();
  506.                     m_pop();
  507.             exit (1);
  508.             break;
  509.         }
  510.         if (At (position))
  511.         position = op;
  512.     }
  513.     }
  514. }
  515.